package com.example.demo.util;

import okhttp3.*;

import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * OkHttp 增强版HTTP工具类
 * <mcurl name="完整文档参考" url="https://square.github.io/okhttp/"></mcurl>
 */
public class HttpUtilOpti {
    // 浏览器特征配置
    private static final Map<String, String> BROWSER_HEADERS;
    static {
        Map<String, String> headers = new HashMap<>();
        headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");
        headers.put("Accept-Language", "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7");
        headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
        headers.put("Sec-Fetch-Site", "none");
        headers.put("Sec-Fetch-Mode", "navigate");
        BROWSER_HEADERS = Collections.unmodifiableMap(headers);
    }

    private static final OkHttpClient client = new OkHttpClient.Builder()
        .addInterceptor(new BrowserHeaderInterceptor())
        .cookieJar(new MemoryCookieJar())
            .connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .connectionPool(new ConnectionPool(5, 5, TimeUnit.MINUTES))
            .addInterceptor(new LoggingInterceptor())
            .cache(new Cache(new File("http_cache"), 10 * 1024 * 1024))
            .build();

    /**
     * 同步GET请求
     * 
     * @param url 请求地址
     * @return 响应体字符串
     * @throws IOException 网络异常或状态码非200
     */
    public static String get(String url) throws IOException {
        Request request = new Request.Builder().url(url).build();
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful())
                throw new IOException("Unexpected code " + response.code());
            return response.body().string();
        }
    }

    // 异步GET方法
    public static void getAsync(String url, Callback callback) {
        Request request = new Request.Builder().url(url).build();
        client.newCall(request).enqueue(callback);
    }

    // 日志拦截器
        // 浏览器头拦截器
    private static class BrowserHeaderInterceptor implements Interceptor {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request original = chain.request();
            Request modified = original.newBuilder()
                .headers(Headers.of(BROWSER_HEADERS))
                .build();
            return chain.proceed(modified);
        }
    }

    // 内存Cookie存储
    private static class MemoryCookieJar implements CookieJar {
        private final Map<HttpUrl, List<Cookie>> cookieStore = new ConcurrentHashMap<>();

        @Override
        public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
            cookieStore.put(url, cookies);
        }

        @Override
        public List<Cookie> loadForRequest(HttpUrl url) {
            return cookieStore.getOrDefault(url, Collections.emptyList());
        }

    }

    private static class LoggingInterceptor implements Interceptor {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            System.out.println("Request: " + request.url());
            Response response = chain.proceed(request);
            System.out.println("Response: " + response.code());
            return response;
        }
    }

    public static String postJson(String url, String json) throws IOException {
        RequestBody body = RequestBody.create(json, MediaType.get("application/json"));
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        try (Response response = client.newCall(request).execute()) {
            return response.body().string();
        }
    }
}
